package cn.com.chengmandian.bike.controller;

import cn.com.chengmandian.bike.dto.AliMiniPhoneLoginForm;
import cn.com.chengmandian.bike.model.EbMemberInfo;
import cn.com.chengmandian.bike.pojo.UserCodeInfo;
import cn.com.chengmandian.bike.service.IEbMemberBlackService;
import cn.com.chengmandian.bike.service.IEbMemberInfoService;
import cn.com.chengmandian.bike.utils.AliMiniUtil;
import cn.com.chengmandian.core.common.constants.CommonConstant;
import cn.com.chengmandian.core.redis.cache.AgentParamCacheService;
import cn.com.chengmandian.core.redis.service.RedisService;
import cn.com.chengmandian.core.web.exceptions.BadResponseException;
import cn.com.chengmandian.core.web.pojo.AgentInfo;
import cn.com.chengmandian.core.web.pojo.AjaxResult;
import cn.com.chengmandian.core.web.pojo.BikeParam;
import cn.com.chengmandian.core.web.utils.LocalMapUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@Slf4j
@Api(tags = "支付宝小程序相关接口")
@RestController
@RequestMapping("/ali/mini")
public class AliMiniController {

    @Autowired
    private IEbMemberInfoService memberInfoService;

    @Autowired
    private IEbMemberBlackService memberBlackService;

    @Autowired
    private AgentParamCacheService agentParamCacheService;

    @Autowired
    private RedisService redisService;

    @ApiOperation("支付宝小程序登录(无需登录)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "登录code")
    })
    @PostMapping("/login")
    public AjaxResult login(String code) throws Exception {
        Assert.isTrue(StrUtil.isNotBlank(code), "缺少code");
        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        Assert.isTrue(StrUtil.isNotBlank(agentInfo.getAliMiniAppid()), "缺少支付宝参数");
        Map responseParam = AliMiniUtil.alipayLogin(code, agentInfo);
        String aliUserId = MapUtil.getStr(responseParam, "user_id", null);
        String aliOpenId = MapUtil.getStr(responseParam, "open_id", null);
        // 支付登录用户唯一标识 user_id 和 open_id 至少有一个标识的值不为空
        if(StrUtil.isBlank(aliUserId) && StrUtil.isBlank(aliOpenId)) throw new BadResponseException("解析code失败");

        if(StrUtil.isBlank(aliUserId)) {
            EbMemberInfo memberInfo = memberInfoService.getByAliPayOpenId(aliOpenId);
            if (memberInfo != null) {
                Assert.isTrue(memberInfo.getIsEnabled().equals(CommonConstant.ONE), "账号已被禁用");
                String token = memberInfoService.getToken(memberInfo);
                Map res = MapUtil.of("token", token);
                res.put("aliPayOpenId", memberInfo.getAlipayOpenId());
                return AjaxResult.success(res);
            }
            return AjaxResult.success(MapUtil.of("aliPayOpenId", aliOpenId));
        }
        EbMemberInfo memberInfo = memberInfoService.getByAliPayUserId(aliUserId);
        if (memberInfo != null) {
            Assert.isTrue(memberInfo.getIsEnabled().equals(CommonConstant.ONE), "账号已被禁用");
            String token = memberInfoService.getToken(memberInfo);
            Map res = MapUtil.of("token", token);
            res.put("aliPayUserId", memberInfo.getAlipayUserId());
            return AjaxResult.success(res);
        }
        return AjaxResult.success(MapUtil.of("aliPayUserId", aliUserId));
    }

    @ApiOperation("通过手机号登陆(无需登录)")
    @PostMapping("/phone/login")
    public AjaxResult loginByPhone(@RequestBody AliMiniPhoneLoginForm aliMiniPhoneLoginForm) throws Exception {
        AgentInfo agentInfo = LocalMapUtil.getAgentInfo();
        String phone =  AliMiniUtil.phone(aliMiniPhoneLoginForm.getResponse(), aliMiniPhoneLoginForm.getSign(), agentInfo.getAliMiniDecryptKey(), agentInfo.getAliPayPublicCertPath());
        Assert.isTrue(StrUtil.isNotBlank(phone), "手机号不正确");
        phone = phone.replace("+", "");
        phone = phone.replace("-", "");
        if (phone.length() != 11) {
            log.error("用户手机号长度不对：{}", phone);
            throw new BadResponseException("手机号不合规");
        }
        EbMemberInfo memberInfo = memberInfoService.getByPhone(phone);
        //判断手机号是否拉黑
        memberBlackService.checkPhone(phone);
        if(ObjectUtil.isNotNull(memberInfo)){
            // 检验身份证号
            memberBlackService.checkIdCard(memberInfo.getIdCard());
        }
        if (memberInfo != null) {
            Assert.isTrue(memberInfo.getIsEnabled().equals(CommonConstant.ONE), "账号已被禁用");
            // 支付宝用户唯一标识user_id
            if(StrUtil.isNotBlank(aliMiniPhoneLoginForm.getAliPayUserId())) {
                if (StrUtil.isBlank(memberInfo.getAlipayUserId()) || !memberInfo.getAlipayUserId().equals(aliMiniPhoneLoginForm.getAliPayUserId())) {
                    memberInfoService.updateAliPayUserId(memberInfo.getId(), aliMiniPhoneLoginForm.getAliPayUserId());
                }
            }else {
                if (StrUtil.isBlank(memberInfo.getAlipayOpenId()) || !memberInfo.getAlipayOpenId().equals(aliMiniPhoneLoginForm.getAliPayOpenId())) {
                    memberInfoService.updateAliPayOpenId(memberInfo.getId(), aliMiniPhoneLoginForm.getAliPayOpenId());
                }
            }
        } else {
            BikeParam bikeParam = agentParamCacheService.getParam(agentInfo.getId());
            if (bikeParam.getUserAgentRegisterAuthEnabled() != null && bikeParam.getUserAgentRegisterAuthEnabled()) {
                UserCodeInfo registerInfo = new UserCodeInfo().setMobile(phone)
                    .setAreaId(agentInfo.getAreaId())
                    .setAliPayUserId(aliMiniPhoneLoginForm.getAliPayUserId())
                    .setAliPayOpenId(aliMiniPhoneLoginForm.getAliPayOpenId());
                String userCode = StrUtil.uuid();
                redisService.set("CMD:BIKE:"+ agentInfo.getId() + ":USERCODE:" + userCode, registerInfo, 60 * 60 * 3);
                JSONObject data = new JSONObject();
                data.put("userCode", userCode);
                throw new BadResponseException(501, "请先实名认证", data);
            }
            memberInfo = memberInfoService.createMember(agentInfo.getAreaId(), phone, null, aliMiniPhoneLoginForm.getAliPayUserId(), aliMiniPhoneLoginForm.getAliPayOpenId());
        }
        String token = memberInfoService.getToken(memberInfo);
        return AjaxResult.success(MapUtil.of("token", token));
    }
}
